﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Diagnostics.CodeAnalysis;

using Fuse8.DomainFramework.Domain;
using Fuse8.DomainFramework.Common.Logging;

namespace Fuse8.DomainFramework.BusinessService
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    public interface IEntityBusinessService<TEntity, TKey> 
        where TEntity : class, IEntityObject<TKey>
        where TKey : IComparable<TKey>, IEquatable<TKey> 
    {
        /// <summary>
        /// 
        /// </summary>
        TEntity Entity { get; }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityObject"></param>
        void Add(TEntity entityObject);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityObject"></param>
        void Save(TEntity entityObject);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityObject"></param>
        void Remove(TEntity entityObject);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        void Remove(TKey id);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        TEntity FindOne(TKey id);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
            Justification = "Uses non-compiled linq expression")]
        TEntity FindOne(Expression<Func<TEntity, bool>> expression);

    	/// <summary>
    	/// 
    	/// </summary>
    	/// <param name="expression"></param>
    	/// <param name="selectExpression"></param>
    	/// <returns></returns>
    	[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
            Justification = "Uses non-compiled linq expression")]
		TEntity FindOne(Expression<Func<TEntity, bool>> expression, Expression<Func<TEntity, object>> selectExpression);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
            Justification = "Uses non-compiled linq expression")]
        IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> expression);

    	/// <summary>
    	/// 
    	/// </summary>
    	/// <param name="expression"></param>
    	/// <param name="selectExpression"></param>
    	/// <returns></returns>
    	[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures",
            Justification = "Uses non-compiled linq expression")]
		IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> expression, Expression<Func<TEntity, object>> selectExpression);

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        IEnumerable<TEntity> FindAll();

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        IEnumerable<TEntity> FindAll(Expression<Func<TEntity, object>> selectExpression);
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        TEntity FindOne(IEntityCommand<TEntity> command);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="clearDependency"></param>
        /// <returns></returns>
        TEntity FindOne(IEntityCommand<TEntity> command, bool clearDependency);
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        IEnumerable<TEntity> Find(IEntityCommand<TEntity> command);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="clearDependency"></param>
        /// <returns></returns>
        IEnumerable<TEntity> Find(IEntityCommand<TEntity> command, bool clearDependency);
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        void Execute(IEntityCommand<TEntity> command);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [Obsolete("Use FindOne method instead")]
        TEntity FindOneByCommand(IEntityCommand<TEntity> command);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="clearDependency"></param>
        /// <returns></returns>
        [Obsolete("Use FindOne method instead")]
        TEntity FindOneByCommand(IEntityCommand<TEntity> command, bool clearDependency);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        [Obsolete("Use Find method instead")]
        IEnumerable<TEntity> FindByCommand(IEntityCommand<TEntity> command);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <param name="clearDependency"></param>
        /// <returns></returns>
        [Obsolete("Use Find method instead")]
        IEnumerable<TEntity> FindByCommand(IEntityCommand<TEntity> command, bool clearDependency);

    }
}
